﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using VFCons;

namespace VFTray
{
    public partial class WndRun : Form
    {

		List<WndPictureS> list_wnps = new List<WndPictureS>();
		List<MessageText> list_msg = new List<MessageText>();
		void createAsCfg(Config.WndObject co, TableLayoutPanel container)
		{
			if (co.Name == "table")
			{
				var nc = createTableLayout(co.Width_col, co.Height_row);
				container.Controls.Add(nc, co.col, co.row);
				for (int i = 0; i < container.ColumnCount * container.RowCount && i < co.Objects.Count; i++)
				{
					var suo = co.Objects[i];
					createAsCfg(suo, nc);
				}
			}
			else if (co.Name == "picture")
			{
				var pit = createPicture();
				list_wnps.Add(pit);
				pit.OnDrawOnBufferedGraphics += Pit_OnDrawOnBufferedGraphics;
				pit.OnDrawOnPaintGraphics += Pit_OnDrawOnPaintGraphics;
				container.Controls.Add(pit, co.col, co.row);
				strTime.Add("");
				strResult.Add("CV Ready");
			}
			else if (co.Name == "MessageText")
			{
				var mt = createMessageText();
				mt.MaxCount = 40;
				list_msg.Add(mt);
				container.Controls.Add(mt, co.col, co.row);
			}
		}

		FeedTray GetFeed(int tag)
		{
			FeedTray Feed = null;
			try
			{
				Feed = GlobalParams.PC.Feeders[tag];
			}
			catch (Exception ex)
			{
				System.Diagnostics.Debug.WriteLine(ex.Message);
			}
			return Feed;
		}

		private void Pit_OnDrawOnPaintGraphics(WndPictureS pthis, Graphics g, float alpha, RectangleF rectImg)
		{
			int tag = Convert.ToInt32(pthis.Tag);
			FeedTray Feed = GetFeed(tag);
			if (Feed == null) return;

			g.DrawString(Feed.GetCfgFeed().cfgCamera.Name + " " + strTime[tag], Font, Brushes.GhostWhite, 50, 50);
			g.DrawString(strResult[tag], Font, Brushes.GhostWhite, 50, 70);
		}

		internal void drawCVResult(Graphics g, float alpha, RectangleF rectImg, List<LLCVApi.LLCV.ResultItem> cvdata)
		{
			Pen pres = new Pen(Color.Blue, 3);
			foreach(var md in cvdata)
			{
				if (md.method == 0)//circle
				{
					RectangleF rtc = new RectangleF((md.center.X - md.markData.U) * alpha + rectImg.X, (md.center.Y - md.markData.U) * alpha + rectImg.Y,
						(md.markData.U + md.markData.U) * alpha, (md.markData.U + md.markData.U) * alpha);
					g.DrawEllipse(pres, rtc);
					string txt = md.r_center.ToString("F2");
					g.DrawString(txt, new Font(Font.FontFamily, 10, FontStyle.Regular), Brushes.Blue, rtc.X, rtc.Y);

				}
				else if (md.method == 1)//rect
				{
					float de = (float)(md.degree);

					PointF center = new PointF(md.center.X * alpha + rectImg.X, md.center.Y * alpha + rectImg.Y);
					g.TranslateTransform(center.X, center.Y);
					g.RotateTransform(-de);
					RectangleF rtc = new RectangleF(-(md.markData.X * 0.5F) * alpha, -(md.markData.Y * 0.5F) * alpha, md.markData.X * alpha, md.markData.Y * alpha);
					g.DrawRectangle(pres, rtc.X, rtc.Y, rtc.Width, rtc.Height);
					g.RotateTransform(de);
					g.TranslateTransform(-center.X, -center.Y);

					string txt = md.r_center.ToString("F2");
					g.DrawString(txt, new Font(Font.FontFamily, 10, FontStyle.Regular), Brushes.Blue, rtc.X, rtc.Y);
				}
				else if (md.method == 2)//template match
				{
					var de = md.degree;
					PointF center = new PointF(md.center.X * alpha + rectImg.X, md.center.Y * alpha + rectImg.Y);
					//g.TranslateTransform(center.X, center.Y);
					//g.RotateTransform(-de);

					PointF pt0 = new PointF(md.pts[0].X * alpha + rectImg.X, md.pts[0].Y * alpha + rectImg.Y);
					PointF pt1 = new PointF(md.pts[1].X * alpha + rectImg.X, md.pts[1].Y * alpha + rectImg.Y);
					PointF pt2 = new PointF(md.pts[2].X * alpha + rectImg.X, md.pts[2].Y * alpha + rectImg.Y);
					PointF pt3 = new PointF(md.pts[3].X * alpha + rectImg.X, md.pts[3].Y * alpha + rectImg.Y);

					g.DrawLine(pres, pt0, pt1);
					g.DrawLine(pres, pt1, pt2);
					g.DrawLine(pres, pt2, pt3);
					g.DrawLine(pres, pt3, pt0);
					string txt = md.similarity.ToString("F0") + " a=" + md.degree.ToString("F0");
					g.DrawString(txt, new Font(Font.FontFamily, 10, FontStyle.Regular), Brushes.Blue, center);

					g.FillEllipse(Brushes.Blue, center.X - 5, center.Y - 5, 10, 10);
					var dfc = md.focus - md.center;
					if (Math.Abs(dfc.X) < 1 && Math.Abs(dfc.Y) < 1)
					{
					}
					else
					{
						g.FillEllipse(Brushes.Orange, md.focus.X * alpha + rectImg.X - 5, md.focus.Y * alpha + rectImg.Y - 5, 10, 10);
					}
					//g.RotateTransform(de);
					//g.TranslateTransform(-center.X, -center.Y);
				}
			}

		}

	

		private void Pit_OnDrawOnBufferedGraphics(WndPictureS pthis, Graphics g, float alpha, RectangleF rectImg)
		{
			DrawHelper.DrawImageRect(g, alpha, rectImg, Pens.White);

			int tag = Convert.ToInt32(pthis.Tag);
			FeedTray Feed = GetFeed(tag);
			if (Feed == null) return;
			if (pthis.Image == null) return;

			var cvp = Feed.GetVision(0);
			if (Feed.CountRequired2 > 0) cvp = Feed.GetVision(Feed.Index_Mark2);
			else cvp = Feed.GetVision(Feed.Index_Mark1);
			//DrawHelper.DrawROI(g, alpha, rectImg, new RectangleF(cvp.roi_x, cvp.roi_y, cvp.roi_w, cvp.roi_h), Color.BlueViolet, Font);
			lock (Feed)
			{
				drawCVResult(g, alpha, rectImg, Feed.cvData);
			}
		}

		private List<string> strTime=new List<string>();
		private List<string> strResult = new List<string>();//"CV Ready";
		internal void SetPicture(int idx_feed, Image img)
		{
			if (list_wnps.Count < idx_feed) return;
			strTime[idx_feed] = DateTime.Now.ToString("HH:mm:ss fff");
			if (InvokeRequired)
			{
				Invoke(new Action(() =>
				{
					list_wnps[idx_feed].Image = img;
				}));
			}
			else
			{
				list_wnps[idx_feed].Image = img;
			}
		}
		internal void UpdatePicture(int iD, string v)
		{
			if (iD < 0 || list_wnps.Count < iD) return;
			strResult[iD] = v;
			if (InvokeRequired)
			{
				Invoke(new Action(() =>
				{
					list_wnps[iD].Invalidate();
				}));
			}
			else list_wnps[iD].Invalidate();
		}

		internal void AddMessage(int idx_feed, string message)
		{
			if (InvokeRequired)
			{
				Invoke(new Action(() =>
				{
					if (list_msg.Count < idx_feed) return;
					list_msg[idx_feed].AddMessage(message);
				}));
			}
			else
			{
				if (list_msg.Count < idx_feed) return;
				list_msg[idx_feed].AddMessage(message);
			}
		}

		public WndRun()
        {
            InitializeComponent();
			var cfg = GlobalParams.CD.WndLayout;
			resizeTableLayout(tableLayoutPanel1, cfg.Width_col.Count, cfg.Height_row.Count);

			int TC = cfg.Width_col.Count * cfg.Height_row.Count;
			for (int i = 0; i < TC&&i<cfg.Objects.Count; i++)
			{
				var o = cfg.Objects[i];
				createAsCfg(o, tableLayoutPanel1);
			}

			VisibleChanged += (s, e) =>
			  {
				  if (Visible)
				  {
					  foreach (var mb in list_msg)
					  {
						  mb.ScrollToEnd();
					  }
				  }
			  };
		}

		private void resizeTableLayout(TableLayoutPanel tp,int ccount,int rcount)
		{
			tp.ColumnStyles.Clear();
			float pre = 100.0F / ccount;
			for (int i = 0; i < ccount; i++)
			{
				tp.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, pre));
			}
			tp.ColumnCount = ccount;
			
			pre = 100.0F / rcount;
			for (int i = 0; i < rcount; i++)
			{
				tp.RowStyles.Add(new RowStyle(SizeType.Percent, pre));
			}
			tp.RowCount = rcount;
		}

		List<TableLayoutPanel> list_tables = new List<TableLayoutPanel>();
		private TableLayoutPanel createTableLayout(List<Config.WidthType> cols, List<Config.WidthType> rows)
		{
			TableLayoutPanel tlp = new TableLayoutPanel();
			tlp.BackColor = System.Drawing.Color.Gainsboro;
			tlp.ColumnCount = cols.Count;
			for (int i = 0; i < cols.Count; i++)
			{
				tlp.ColumnStyles.Add(new ColumnStyle((SizeType)cols[i].Type, cols[i].Width));
			}
			tlp.Dock = DockStyle.Fill;
			tlp.Location = new System.Drawing.Point(0, 0);
			tlp.Name = "tableLayoutPanel_Create_"+ list_tables.Count.ToString();

			tlp.RowCount = rows.Count;
			for (int i = 0; i < rows.Count; i++)
			{
				tlp.RowStyles.Add(new RowStyle((SizeType)rows[i].Type, rows[i].Width));
			}
			tlp.Size = new System.Drawing.Size(800, 450);
			tlp.Dock = DockStyle.Fill;
			return tlp;
		}
		private Button createButton()
		{
			Button btn = new Button();
			btn.Location = new System.Drawing.Point(403, 3);
			btn.Name = "button1";
			btn.Size = new System.Drawing.Size(75, 23);
			btn.TabIndex = 0;
			btn.Text = "button1";
			btn.UseVisualStyleBackColor = true;
			return btn;
		}

		private WndPictureS createPicture()
		{
			var wnd = new WndPictureS();
			wnd.Alpha = 1F;
			wnd.BackColor = Color.Black;
			wnd.CanZoom = false;
			wnd.Dock = DockStyle.Fill;
			wnd.Image = null;
			wnd.Location = new Point(3, 3);
			wnd.MouseSelecting = false;
			wnd.Name = "wndPicture_create_" + list_wnps.Count.ToString();
			wnd.SelectSequareOrRect = false;
			wnd.Size = new Size(643, 628);
			wnd.TabIndex = 0;
			wnd.TextPos = new Point(50, 50);
			wnd.Tag = list_wnps.Count;
			return wnd;
		}

		private MessageText createMessageText()
		{
			var con = new MessageText();
			con.Dock = DockStyle.Fill;
			return con;
		}

		internal void Init()
		{
		}

		internal void OnUiTimer()
		{
		}

		internal void UpdateAuth()
		{
		}
	}
}
